﻿using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.Phone.Reactive;
using RssReaderTemplate.Model;
using System.Windows;
using RssReaderTemplate.Model.Mappers;

namespace RssReaderTemplate.Repositories
{
    public class RssRepository : IObservable<RssItem>
    {
        private Uri _rssUrl;
        private NetworkMonitor _monitor;
        private ISubject<RssItem> _rssItems = new ReplaySubject<RssItem>();
        public Uri RssUrl
        {
            get { return _rssUrl; }
        }


        public RssRepository(string rssUrl, NetworkMonitor monitor)
        {
            _rssUrl = new Uri(rssUrl);
            _monitor = monitor;
        }

        public IDisposable Connect()
        {
            WebClient client = new WebClient();
            //var query = (from ev in Observable.FromEvent<DownloadStringCompletedEventArgs>(client, "DownloadStringCompleted")
            //            select GetRssItems(ev.EventArgs.Result) into result
            //            from r in result
            //            select r);
            var query = Observable.FromEvent<DownloadStringCompletedEventArgs>(client, "DownloadStringCompleted").SelectMany(x =>
            {
                if (x.EventArgs.Cancelled){
                    return Observable.Empty<RssItem>();
                } else if(x.EventArgs.Error != null)
                {
                    _rssItems.OnError(x.EventArgs.Error);
                    return Observable.Empty<RssItem>();
                }
                else
                {
                    return GetRssItems(x.EventArgs.Result);
                }
            });
            var startObserving = _monitor.DistinctUntilChanged().Where(x => x == true).TakeUntil(query);
                                 
            return new CompositeDisposable(query.Subscribe(_rssItems),
                startObserving.Subscribe(x => client.DownloadStringAsync(_rssUrl)));
        }

        public IDisposable Subscribe(IObserver<RssItem> observer)
        {
            return _rssItems.Subscribe(observer);
        }

        private IObservable<RssItem> GetRssItems(string rssFeed)
        {
            var mapper = new RssParser(rssFeed);
            return mapper.ParseFeed().ToObservable(Scheduler.ThreadPool);
        }
    }
}
